#include "i2c_slave.h"
#include <stdio.h>
#include "SEGGER_RTT.h"
#include "sc16is7xx.h"
#include "i2c.h"

struct i2c_slave_data_t i2c_data;
extern I2C_HandleTypeDef hi2c1;

unsigned char i2cs_default_data[256] = {
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,

  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00  
};
unsigned char sval = 0;
unsigned int gcnt = 0;
unsigned char tbuf[256+4];
unsigned char rbuf[256+4];
extern i2c_slave_init_t i2c_init;
void I2C_Delay(unsigned int t)
{
	unsigned int i;
	for(i=0;i<t+5;i++)
		for(int j=0;j<100;j++)
			;
}
void I2C_Slave_Init(i2c_slave_init_t *i2c_init)
{
  int i;
  i2c_data.i2cs_state  = I2C_CMD_IDLE;
  i2c_data.i2cs_register = 0;
  for( i=0;i<0xff;i++)
    i2c_data.i2cs_memory[i] = i2cs_default_data[i];
	for( i=0;i<64+4;i++)
		tbuf[i] = i;
  //_error_handler = i2c_init->error_handler;
	
	HAL_I2C_EnableListen_IT(i2c_init->hi2c);

}

void I2C_Error_Handler(){
  //_error_handler();
	printf("Error_Handler\r\n");
	//MX_I2C1_Init();
    //I2C_Slave_Init(&i2c_init);

	//HAL_I2C_EnableListen_IT(&hi2c1);

}


// 地址中断回调函数，包括读和写
// 设备地址匹配的中断
unsigned short wreg;
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t direction, uint16_t addrMatchCode) {
	if(hi2c->Instance == I2C1)
	{
		switch (direction) {
			case I2C_DIRECTION_TRANSMIT: 		//  写，第一个写数据为寄存器地址     
				i2c_data.i2cs_state  = I2C_SLAVE_ADDR;  // 进入到地址阶段
				//  接收一个字节的数据,下一个数据作为寄存器地址
				//  获取到地址后边一般会写1或者2个地址字节
				if (HAL_I2C_Slave_Seq_Receive_IT(hi2c, (uint8_t *)&wreg, 2, I2C_FIRST_FRAME) != HAL_OK) {
					I2C_Error_Handler();
				}
				HAL_GPIO_TogglePin(CODEC_PUSH_PORT, CODEC_PUSH_PIN);
	 
			break;
				// 主机接收数据，需要再次发送数据
				// 发完设备地址后，如果是读指令，则直接返回数据了
			case I2C_DIRECTION_RECEIVE:			// 读 MASTER IIC_READ
				
				i2c_data.i2cs_state  = I2C_GET_DATA;			// ̬读取 SLAVE 的数据
				//sc16is7xx_ops_read(&i2c_data.i2c_addr,i2c_data.i2cs_txbuf);        // read data from slave
			
				HAL_GPIO_TogglePin(CODEC_PUSH_PORT, CODEC_PUSH_PIN);
				tbuf[0] = i2c_data.i2cs_register;
				if (HAL_I2C_Slave_Seq_Transmit_IT(hi2c, tbuf, wreg, I2C_FIRST_AND_LAST_FRAME) != HAL_OK) {
					I2C_Error_Handler();
					SEGGER_RTT_printf(0,"HAL_I2C_Slave_Seq_Transmit_IT\r\n");
				}

			break;
			default:
				I2C_Error_Handler();
			break;
		}
	}
}
// 接收完成中断,STM32接收到数据
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) 
{
	if(hi2c->Instance == I2C1)
	{
		switch (i2c_data.i2cs_state ) 
		{
			case I2C_SLAVE_ADDR:      // 第1个字节是寄存器地址
				//SEGGER_RTT_printf(0,"GR %0x\n",wreg);
				i2c_data.i2cs_register = wreg % 256;		// 寄存器地址
				wreg = wreg/256;  // 接收长度
				i2c_data.i2cs_state  = I2C_PUT_DATA;												// ̬进入获取数据阶段
			
				// 开始接收下一个数据中断
				if (HAL_I2C_Slave_Seq_Receive_IT(hi2c,rbuf, wreg, I2C_NEXT_FRAME) != HAL_OK) {
						I2C_Error_Handler();
						SEGGER_RTT_printf(0,"I2C_PUT_DATA HAL_I2C_Slave_Seq_Receive_IT\r\n");
				}
			break;
				// 上边接收完成后会进入这里接收数据
			case I2C_PUT_DATA:
				HAL_GPIO_TogglePin(CODEC_PUSH_PORT, CODEC_PUSH_PIN);
				//SEGGER_RTT_printf(0,"msd %0x\n",rbuf[0]);
				if (HAL_I2C_Slave_Seq_Receive_IT(hi2c, rbuf, wreg, I2C_NEXT_FRAME) != HAL_OK) {
					I2C_Error_Handler();
					SEGGER_RTT_printf(0,"I2C_PUT_DATA HAL_I2C_Slave_Seq_Receive_IT\r\n");

				}
				//sc16is7xx_ops_write(&i2c_data.i2c_addr,i2c_data.i2cs_rxbuf);
			 
			break;
			default:
				I2C_Error_Handler();
			break;
		}
	}
}
// IIC Slave 发送数据完成
// 发送一次完成后第2次会进入这里
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
	if(hi2c->Instance == I2C1)
	{	
		//HAL_GPIO_TogglePin(CODEC_PUSH_PORT, CODEC_PUSH_PIN);
		//SEGGER_RTT_printf(0,"msd %0x\n",rbuf[0]);
		if (HAL_I2C_Slave_Seq_Transmit_IT(hi2c, tbuf, 64, I2C_FIRST_AND_LAST_FRAME) != HAL_OK) {
			I2C_Error_Handler();
			SEGGER_RTT_printf(0,"HAL_I2C_SlaveTxCpltCallback HAL_I2C_Slave_Seq_Transmit_IT\r\n");
		} 
	}
    //SEGGER_RTT_printf(0,"ok\nSend %x ",sval);

}
// IIC Slave 监听
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) {
	if(hi2c->Instance == I2C1)
	{
		#if 1
			i2c_data.i2cs_register = 0;
			i2c_data.i2cs_state  = I2C_CMD_IDLE;
			HAL_GPIO_TogglePin(CODEC_PUSH_PORT, CODEC_PUSH_PIN);

			HAL_I2C_EnableListen_IT(hi2c);
			//SEGGER_RTT_printf(0,"ListenCplt\n");

		#endif
	}
}

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
// 根据hi2c->ErrorCode的值来判断错误类型
	uint32_t ErrorCode = hi2c->ErrorCode;
	SEGGER_RTT_printf(0,"%d\n",ErrorCode);

	if(hi2c->Instance == I2C1)
	{
		#if 1
		if (ErrorCode & HAL_I2C_ERROR_AF)
		{

			// 当从接收器接收到一个NACK，则需要释放总线
			if((i2c_data.i2cs_state  == I2C_PUT_DATA)|| (i2c_data.i2cs_state  == I2C_GET_DATA))		// 写数据完成
			{
				//for(int i=0;i<hi2c->XferCount;i++)
				//	//SEGGER_RTT_printf(0,"%02x ",rbuf[i]);
				////SEGGER_RTT_printf(0,"\r\n");
				////SEGGER_RTT_printf(0,"%0d\r\n",hi2c->XferCount);

				#if 1
						i2c_data.i2cs_register = 0;
						i2c_data.i2cs_state  = I2C_CMD_IDLE;
						// 重新初始化会多出现一个停止位
						//HAL_I2C_DeInit(hi2c);
						//MX_I2C1_Init();
				#endif	
				HAL_I2C_EnableListen_IT(hi2c);

			}
			else
			{
				HAL_I2C_DeInit(hi2c);
				MX_I2C1_Init();	
				HAL_I2C_EnableListen_IT(hi2c);
				I2C_Slave_Init(&i2c_init);

			}
		}
		else if(ErrorCode & HAL_I2C_ERROR_BERR)
		{
				i2c_data.i2cs_register = 0;
				i2c_data.i2cs_state  = I2C_CMD_IDLE;
				HAL_I2C_DeInit(hi2c);
				MX_I2C1_Init();	
				HAL_I2C_EnableListen_IT(hi2c);
				I2C_Slave_Init(&i2c_init);	
		}
		else if(ErrorCode & HAL_I2C_ERROR_TIMEOUT)
		{
					// 处理I2C_SR1_TIMEOUT位被设置的超时错误
					SEGGER_RTT_printf(0,"HAL_I2C_ERROR_TIMEOUT\r\n");
		}
		else if (ErrorCode & HAL_I2C_ERROR_ARLO){

					// 处理I2C_SR1_ARLO位被设置的Arlos错误
					SEGGER_RTT_printf(0,"HAL_I2C_ERROR_TIMEOUT\r\n");

		}
		else if (ErrorCode & HAL_I2C_ERROR_OVR){

					// 处理I2C_SR1_OVR位被设置的Overrun错误
					SEGGER_RTT_printf(0,"HAL_I2C_ERROR_TIMEOUT\r\n");

		}
		else if (ErrorCode & HAL_I2C_ERROR_DMA){

					// 处理DMA相关的错误
					SEGGER_RTT_printf(0,"HAL_I2C_ERROR_DMA\r\n");
		}
		else{
					// 处理其他错误
					SEGGER_RTT_printf(0,"HAL_I2C_ERROR_default %02x\r\n",hi2c->ErrorCode);
		}				
		#endif
	}
}
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
{
	SEGGER_RTT_printf(0,"HAL_I2C_AbortCpltCallback %x\n",sval);
}
/*
i2c_tools 
i2ctransfer -fy 0 r2@0x36   
i2cdump 0 0x36 -fy c
i2cdetect -y -a 2
root@FriendlyARM:/# i2ctransfer -f -y 2 w5@0x36 0x00 0x55 0x56 0x57 0x58    
i2cget -f -y 2 0x36 0x58
// 读取 中断识别寄存器 IIC
i2cget -f -y 2 0x36 0x20

i2cset -f -y 2 0x36 0x00 0xA1 b

tftp 192.168.0.60 -g -r btn
串口0写
i2ctransfer -f -y 2 w9@0x36 0x00 0x55 0x56 0x57 0x58 0x59 0x55 0x56 0x55
串口1
i2ctransfer -f -y 2 w9@0x36 0x01 0x55 0x56 0x57 0x58 0x59 0x55 0x56 0x55

i2cdetect  -y 2 0x36 0x36
i2ctransfer -f -y 2 r9@0x36

/sys/class/gpio
# echo 503 > export
*/
